use crate::{
    db::connect_to_db,
    handlers::get_user,
    helpers::{count_ttr, create_ttr, wrap_url, Bot},
    models::{Post, UserPost},
};
use anyhow::{Context, Result};
use futures::StreamExt;
use mongodb::{
    bson::{doc, from_document, spec::BinarySubtype, Binary},
    Database,
};
use teloxide::{
    prelude::*,
    types::{
        InlineKeyboardButton, InlineKeyboardButtonKind, InlineKeyboardMarkup,
    },
    utils::markdown::escape_link_url,
};
use uuid::Uuid;
pub async fn get_post_info(bot: Bot, q: CallbackQuery, data: &str) -> Result<()> {
    let pos = data.find(' ').unwrap();
    let (post_id_str, page_num) = data.split_at(pos);
    println!("{}", page_num);
    let user_id = q.from.id;
    let user = get_user(user_id).await?;
    let message_id = q.message.clone().unwrap().id;
    let chat_id = q.message.clone().unwrap().chat.id;
    let post_id = Uuid::parse_str(post_id_str)?;
    let bin_id = Binary {
        subtype: BinarySubtype::Uuid,
        bytes: post_id.as_bytes().to_vec(),
    };
    let db = connect_to_db().await?;
    let user_post = get_user_post(user.id, bin_id.clone(), &db).await?;
    let post = get_post(bin_id, &db).await?;
    let mut title = {
        if let Some(title) = post.title {
            wrap_url(&user_post.original_url(), &title)
        } else {
            escape_link_url(&user_post.original_url())
        }
    };
    let ttr = count_ttr(post.word_count);
    if let Some(ttr) = ttr {
        create_ttr(&mut title, ttr)
    };
    let text = format!(
        r##"{}
favorite: {}
read: {}
"##,
        title,
        user_post.favorite(),
        user_post.read()
    );
    let archive_button = {
        if user_post.read() {
            InlineKeyboardButton::new(
                "unarchive",
                InlineKeyboardButtonKind::CallbackData(format!("unarchive {}", post_id_str)),
            )
        } else {
            InlineKeyboardButton::new(
                "archive",
                InlineKeyboardButtonKind::CallbackData(format!("archive {}", post_id_str)),
            )
        }
    };
    let favorite_button = {
        if user_post.favorite() {
            InlineKeyboardButton::new(
                "unfavorite",
                InlineKeyboardButtonKind::CallbackData(format!("unfavorite {}", post_id_str)),
            )
        } else {
            InlineKeyboardButton::new(
                "favorite",
                InlineKeyboardButtonKind::CallbackData(format!("favorite {}", post_id_str)),
            )
        }
    };
    let back_button = InlineKeyboardButton::new(
        "back",
        InlineKeyboardButtonKind::CallbackData(format!("page{}", page_num)),
    );
    let buttons = vec![vec![archive_button, favorite_button], vec![back_button]];
    let reply_markup = InlineKeyboardMarkup::new(buttons);
    bot.edit_message_text(chat_id, message_id, text)
        .reply_markup(reply_markup)
        //.parse_mode(MarkdownV2)
        .await?;
    Ok(())
}

async fn get_user_post(user_id: Uuid, post_id: Binary, db: &Database) -> Result<UserPost> {
    let user_coll = db.collection::<UserPost>("userposts");
    let match1_aggr = doc! {
        "$match": {
        "user_id": user_id,
        "post_id": post_id,
        }
    };
    let pipeline = [match1_aggr];
    let post = user_coll
        .aggregate(pipeline, None)
        .await
        .context("lalalala")?
        .next()
        .await
        .context("get_user_post failed")??;
    Ok(from_document::<UserPost>(post)?)
}
async fn get_post(post_id: Binary, db: &Database) -> Result<Post> {
    let coll = db.collection::<Post>("posts");
    let match_aggr = doc! {
        "$match": {
            "id": post_id
        }
    };
    let limit_aggr = doc! {
        "$limit": 1_i32
    };
    let pipeline = [match_aggr, limit_aggr];
    let post = coll
        .aggregate(pipeline, None)
        .await
        .context("hahahahla")?
        .next()
        .await
        .context("get_post failed")??;
    Ok(from_document::<Post>(post)?)
}
